#include "symbol.h"

/**
 * @brief 导出的操作函数
 */
extern akfs_operation_t *__akfs_ops;
extern akfs_module_t __process;
static DEFINE_SPINLOCK(__akfs_chan_lock_process_ptr);

/**
 * @brief __put_ring 
 *   将数据投递到ringl里面
 */
static void __put_ring(akfs_process_t *p){
    spin_lock(&__akfs_chan_lock_process_ptr);
    __akfs_ops->put(&__process.c_args ,p ,PAGE_SIZE);
    spin_unlock(&__akfs_chan_lock_process_ptr);
}

/**
 * @brief __padding_ids
 *   填充id信息
 */
static void __padding_id(akfs_process_t *p ,struct task_struct *task ,
        long pid ,unsigned int type)
{
    p->data_type = type;

    //获取相应id值
    p->pid = pid ? pid : task->pid;
    p->ppid = task->real_parent->pid; 
    p->ptgid = task->real_parent->tgid;
    p->ns = akfs_get_nspid(task);
    p->uid = akfs_get_uid(task);
    p->gid = akfs_get_gid(task);

    //填充时间戳
    p->timestamp = __akfs_ops->get_unixts();

    //填充父进程名
    snprintf(p->parent_name ,sizeof(p->parent_name) ,"%s" ,task->parent ? task->parent->comm : "unknown");
}

/**
 * @brief process_fork_put 
 *   投递fork点数据
 */
void process_fork_put(struct task_struct *task ,long pid)
{
    akfs_process_t *p = NULL;

    p = (akfs_process_t *)__akfs_ops->alloc(__process.c_ring ,1);
    assert_ret(p);

    //填充基本信息
    __padding_id(p ,task ,pid ,PROCESS_TYPE_FORK);
    
    //刷新fork 子进程pid
    p->pid = pid;

    //获取进程全路径 
    __akfs_ops->get_tpath(task ,p->exec_file ,sizeof(p->exec_file));

    __akfs_ops->get_thash(task ,p->exec_hash ,sizeof(p->exec_hash));

    __put_ring(p);

    __akfs_ops->free(__process.c_ring ,p);
}

/**
 * @brief process_bprm_put 
 *   进程exec点获取信息
 */
void process_bprm_put(struct task_struct *task ,struct linux_binprm *bprm)
{
    akfs_process_t *p = NULL;
    int ret;

    p = (akfs_process_t *)__akfs_ops->alloc(__process.c_ring ,1);
    assert_ret(p);

    //填充基本信息
    __padding_id(p ,task ,0 ,PROCESS_TYPE_EXEC);

    //获取进程全路径 
    __akfs_ops->get_fpath(bprm->file ,p->exec_file ,sizeof(p->exec_file));

    __akfs_ops->get_fhash(bprm->file ,p->exec_hash ,sizeof(p->exec_hash));

    //获取参数
    ret = __akfs_ops->get_args(bprm ,p->argv ,sizeof(p->argv));
    assert_goto(!(ret < 0) ,out ,);

    __put_ring(p);

out:
    __akfs_ops->free(__process.c_ring ,p);
}

/**
 * @brief process_exit_put 
 *   进程退出时获取
 */
void process_exit_put(struct task_struct *task)
{
    akfs_process_t *p = NULL;

    p = (akfs_process_t *)__akfs_ops->alloc(__process.c_ring ,1);
    assert_ret(p);

    //填充基本信息
    __padding_id(p ,task ,0 ,PROCESS_TYPE_EXIT);

    //获取进程全路径 
    __akfs_ops->get_tpath(task ,p->exec_file ,sizeof(p->exec_file));

    __akfs_ops->get_thash(task ,p->exec_hash ,sizeof(p->exec_hash));

    __put_ring(p);

    __akfs_ops->free(__process.c_ring ,p);
}

